package drds.plus.executor.function.scalar.string;

import drds.plus.common.utils.TStringUtil;
import drds.plus.executor.ExecuteContext;
import drds.plus.executor.function.scalar.ScalarFunction;
import drds.plus.executor.utils.Utils;
import drds.plus.sql_process.type.Type;

/**
 * <pre>
 * SUBSTRING_INDEX(str,delim,count)
 *
 * Returns the substring from string str before count occurrences of the delimiter delim. If count is positive, everything to the leftNode of the final delimiter (counting from the leftNode) is returned. If count is negative, everything to the rightNode of the final delimiter (counting from the rightNode) is returned. SUBSTRING_INDEX() performs a case-sensitive ruleCalculate when searching for delim.
 *
 * mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);
 *         -> 'www.mysql'
 * mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
 *         -> 'mysql.com'
 *
 * </pre>
 *
 * @author mengshi.sunmengshi 2014年4月15日 下午2:02:15
 * @since 5.1.0
 */
public class SubStringIndex extends ScalarFunction {

    public Type getReturnType() {
        return Type.StringType;
    }

    public String[] getFunctionNames() {
        return new String[]{"SUBSTRING_INDEX"};
    }

    public Object compute(ExecuteContext executeContext, Object[] args) {
        if (Utils.isNull(args[0])) {
            return null;
        }

        String str = Type.StringType.convert(args[0]);
        String delim = Type.StringType.convert(args[1]);
        Integer count = Type.IntegerType.convert(args[2]);
        if (count == 0) {
            return "";
        } else if (count > 0) {
            Integer len = TStringUtil.ordinalIndexOf(str, delim, count);
            if (len == -1) {
                return str;
            }
            return str.substring(0, len);
        } else {
            count = -count;
            Integer pos = TStringUtil.lastOrdinalIndexOf(str, delim, count);
            return str.substring(pos + 1);
        }
    }

}
